package org.iweb.init.servlet;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.iweb.html.api.AbstractHtmlElement;
import org.iweb.html.api.AppState;
import org.iweb.html.api.Listener;
import org.iweb.html.engine.render.IRenderEngine;
import org.iweb.html.impl.basic.Form;
import org.iweb.html.impl.basic.Form.CustomFormBean;
import org.iweb.html.impl.basic.Script;
import org.iweb.html.impl.session.AppSession;
import org.iweb.html.impl.session.MainManager;
import org.iweb.ioc.ServiceLookup;
import org.iweb.ui.layout.DefaultLayout;
import org.iweb.util.JsonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class IWebApplication extends HttpServlet {

	/**
	 *
	 */
	private static final long serialVersionUID = 8115136707579126811L;
	private static Logger log=LoggerFactory.getLogger(IWebApplication.class);

	private Form.CustomFormBean bean;

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		//Non deve servire contenuti statici altrimenti non funziona

		HttpSession session=request.getSession();

		AppSession appSession=(AppSession) session.getAttribute("APPLICATION");

		if(appSession==null){
			appSession=new AppSession();
			appSession.setId(session.getId());
		}

		appSession.setAppState(new AppState());

		MainManager.setAppSession(appSession);

		if(request.getParameter("listenerid")!=null){
			handleActions(request,response,appSession);
			return;
		}

		//elimino i listener in sessione
		MainManager.getAppSession().getObserver().clean();

		AbstractHtmlElement container=render(request,response);

		DefaultLayout layout=getDefaultLayout();
		layout.getPageContainer().append(container);

		if(appSession.getAppState().getScriptElement()!=null && appSession.getAppState().getScriptElement().size()>0)
			layout.getBody().append(new Script(appSession.getAppState().getScriptElement()));

		//response.addHeader("ContentType", "text/html");
		response.getWriter().write(getRenderEngine().render(layout));

		session.setAttribute("APPLICATION",appSession);
		MainManager.clean();
	}

	public IRenderEngine getRenderEngine(){
		return ((IRenderEngine)ServiceLookup.getInstance().get("IRenderEngine"));
	}

	public DefaultLayout getDefaultLayout(){
		return ((DefaultLayout)ServiceLookup.getInstance().get("DefaultLayout"));
	}

	private void handleActions(HttpServletRequest request,
			HttpServletResponse response, AppSession appSession) {
			String listenerid = request.getParameter("listenerid");

			if(listenerid!=null){
				if(appSession.getObserver().getListener(listenerid)!=null){

					String beanid = request.getParameter("beanid");
					log.debug(String.format("BeanId %s ListenerId %s",beanid,listenerid));

					try {
						if (beanid != null && beanid.trim().length() > 0) {
							bean = new Form.BeanFactory().getBean(
									request.getParameterMap(),
									(CustomFormBean) this.getClass().getClassLoader()
											.loadClass(beanid).newInstance());
						}
					} catch (Exception e1) {
						e1.printStackTrace();
					}


					List<Listener> l=appSession.getObserver().getListener(listenerid);

					l.forEach(list->{
						list.run(request, getBean());
					});
				}else{
					response.setStatus(302);
					return;
				}
			}

			response.setContentType("application/json");

			try {
				response.getOutputStream().print(JsonUtil.toJSON(appSession.getAppState().getHtmlState().getElstates()));
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	private CustomFormBean getBean() {
		return bean;
	}

	public abstract AbstractHtmlElement render(HttpServletRequest arg0, HttpServletResponse arg1);

}
